package com.example.base_model.utils

import android.view.View
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch

/**
 * @Author jiangKunKun
 * @CreateDate 2025/8/25
 * @Description 多View防抖动管理器 - 基于Kotlin Flow实现。
 *              用于监控多个View的点击事件，在指定时间内没有新的点击时执行回调。
 *              这有助于防止用户快速重复点击UI元素。
 * @SpittingGrooves
 */
class MultiViewDebounceManager constructor(
    /**
     * 防抖动延迟时间（毫秒），在此时间内连续点击只算一次。
     */
    private val delayMillis: Long,
    /**
     * 需要监控点击事件的View集合。
     */
    private val views: Set<View>,
    /**
     * 协程作用域，用于管理防抖动逻辑的生命周期，通常与UI组件的生命周期绑定。
     */
    private val scope: CoroutineScope,
    /**
     * 防抖动结束后执行的回调动作。
     */
    private val action: () -> Unit
)  {
    /**
     * 一个 [MutableSharedFlow] 用来发射点击事件。它有一个额外的缓冲区容量，确保即使在快速点击时也能处理事件。
     * 每当有View被点击时，都会向这个Flow发射一个 [Unit] 事件。
     */
    private val _clickEvents = MutableSharedFlow<Unit>(extraBufferCapacity = 1)

    init {
        // 在指定的协程作用域中启动一个协程，用于监听点击事件并进行防抖动处理。
        scope.launch {
            _clickEvents
                .debounce(delayMillis)  // 使用 Kotlin Flow 的 debounce 操作符实现防抖动。
                                        // 它会在指定 delayMillis 时间内没有新事件到来时才发射最新的事件。
                .collect {              // 收集防抖动后的事件。
                    action()            // 当收集到事件时，执行预设的回调动作。
                }
        }
        // 立即为所有注册的View设置点击监听器。
        setupClickListener()
    }

    /**
     * 为所有注册的 [views] 设置点击监听器。
     * 当任何一个被监听的 View 被点击时，会向 `_clickEvents` Flow 发射一个事件。
     */
    private fun setupClickListener() {
        views.forEach { view -> // 遍历需要监控的View集合
            view.setOnClickListener { // 为每个View设置点击监听器
                // 当View被点击时，尝试发射一个 Unit 事件到 _clickEvents Flow中。
                // tryEmit 是非挂起函数，如果缓冲区已满或Flow已关闭，它会返回 false 但不会阻塞。
                _clickEvents.tryEmit(Unit)
            }
        }
    }

}